package com.zxpt.quetion.utils;


import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

/**
* 所在包：com.wenhe.template.utils
* 文件名：
* 版权：稻草人.
* 项目：autoTemp
* 功能描述： 和代码生成没有关系，分页查询工具类
* 修改人：wenhe
* 修改时间：2019-11-06 18:21
*/
public class CreateQueryConditionUtil {
    // 不同的字段匹配方式
    public static final String PRE_LIKE = "plike";          // 前模糊
    public static final String LATER_LIKE = "llike";        // 后模糊
    public static final String BOTH_LIKE = "blike";         // 前后模糊
    public static final String EQUAL = "equal";             // 等于操作
    public static final String NOT_EQUAL = "nequal";        // 不等于
    public static final String GREATER_EQUAL = "ge";        // 大于等于
    public static final String LESS_EQUAL = "le";           // 小于等于
    public static final String GREATER = "g";               // 大于
    public static final String LESS = "l";                  // 小于
    public static final String GREATER_EQUAL_TIME = "get";  // 时间大于等于
    public static final String LESS_EQUAL_TIME = "let";     // 时间小于等于
    public static final String GREATER_TIME = "gt";         // 时间大于
    public static final String LESS_TIME = "lt";            // 时间小于

    private static String[] timeFormatArr = {
        "yyyy-MM-dd",
        "yyyy/MM/dd",
        "yyyy-MM-dd HH:mm:ss",
        "yyyy/MM/dd HH:mm:ss"
        };

    /**
    * 根据前端传参拼接查询条件
    *  参数名中包含下划线，拼接like条件，根据下划线的前后位置拼接模糊位置
    * @param map
    * @return
    */
    public static Query createCondition(Map<String, Object> map) {
        String condition = "";
        if (map == null) {
            return null;
        }
        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        // 遍历查询条件拼接查询sql
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            String paramName = next.getKey();
            Object obj = next.getValue();
            if (obj != null) {
                String value = obj.toString();
                // 仅对非空数据进行处理
                if(!StringUtils.isEmpty(value.trim()))
                    condition = condition + createCondition(paramName, value);
            }
        }
        Query query = new Query(condition, map);
        return query;
    }

    /**
    * 根据用户名的状态生成不同的查询条件
    *      类别名__字段名__操作方式
    * @param param
    * @param value
    * @return
    */
    private static String createCondition(String param, String value) {
        String condition = "";
        String[] paramArr = param.split("__");
        // 仅对满足分隔条件的语句进行条件拼接
        if (paramArr.length > 1) {
            String field = "";         // 字段名称
            String alias = null;       // 表别名
            String handleType = "";    // 操作类型
            String column = "";        // 表字段名称
            // 查询条件类型1（表名__匹配方式）
            if (paramArr.length == 2) {
                field = paramArr[0];
                handleType = paramArr[1];
            // 查询条件类型2（表别名__表名__匹配方式）
            } else if (paramArr.length == 3) {
                alias = paramArr[0];
                field = paramArr[1];
                handleType = paramArr[2];
            }
            column = (alias != null ? alias + "." : "") + transCamelToUnderline(field);
            String timeStr = null;
            switch (handleType) {
                case PRE_LIKE:
                    condition = "and " + column + " like '%" + value + "'";
                    break;
                case LATER_LIKE:
                    condition = "and " + column + " like '" + value + "%'";
                    break;
                case BOTH_LIKE:
                    condition = "and " + column + " like '%" + value + "%'";
                    break;
                case EQUAL:
                    condition = "and " + column + " = '" + value + "'";
                    break;
                case NOT_EQUAL:
                    condition = "and " + column + " <> '" + value + "'";
                    break;
                case GREATER:
                    condition = "and " + column + " > '" + value + "'";
                    break;
                case LESS:
                    condition = "and " + column + " < '" + value + "'";
                    break;
                case GREATER_EQUAL:
                    condition = "and " + column + " >= '" + value + "'";
                    break;
                case LESS_EQUAL:
                    condition = "and " + column + " <= '%" + value + "%'";
                    break;
                case GREATER_TIME:
                    timeStr = formatTimeStr(value);
                    if (timeStr != null) {
                        condition = "and " + column + " > str_to_date('" + formatTimeStr(value) + "', '%Y-%m-%d %H:%i:%s')";
                    }
                    break;
                case LESS_TIME:
                    timeStr = formatTimeStr(value);
                    if (timeStr != null) {
                        condition = "and " + column + " < str_to_date('" + formatTimeStr(value) + "', '%Y-%m-%d %H:%i:%s')";
                    }
                    break;
                case GREATER_EQUAL_TIME:
                    timeStr = formatTimeStr(value);
                    if (timeStr != null) {
                        condition = "and " + column + " >= str_to_date('" + formatTimeStr(value) + "', '%Y-%m-%d %H:%i:%s')";
                    }
                    break;
                case LESS_EQUAL_TIME:
                    timeStr = formatTimeStr(value);
                    if (timeStr != null) {
                        condition = "and " + column + " <= str_to_date('" + formatTimeStr(value) + "', '%Y-%m-%d %H:%i:%s')";
                    }
                    break;
                default:
                    break;
            }
        }
        return condition;
    }

    /**
    * 将时间字符串格式化成yyyy-MM-dd HH:mm:ss格式的时间字符串
    * @param timeStr
    * @return
    */
    private static String formatTimeStr(String timeStr) {
        Date date = null;
        for (String format: timeFormatArr) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            try {
                date = simpleDateFormat.parse(timeStr);
            } catch (ParseException e) {
                System.out.println("------------------------------------ " + timeStr + " -----------------------------");
            }
            if (date != null) {
                break;
            }
        }
        if (date != null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = simpleDateFormat.format(date);
            return format;
        }
        return null;
    }

    /**
    * 驼峰转下划线（首字母默认小写）
    * @param str
    * @return
    */
    public static String transCamelToUnderline(String str) {
        char[] chars = str.toCharArray();
        int length = chars.length;
        String underlineStr = "";
        for (int i=0; i< length; i++) {
            char current = chars[i];
            String currentStr = current + "";
            if (i==0) {
                underlineStr = current + "";
                underlineStr = underlineStr.toLowerCase();
            } else {
                if (current >= 65 && current <= 90) {
                underlineStr = underlineStr + "_" + currentStr.toLowerCase();
            } else {
                underlineStr = underlineStr + currentStr;
                }
            }
        }
        return underlineStr;
    }
}
